#include "widget.h"
#include "ui_widget.h"
#include "mysql_data.h"
#include "thread_rdwr.h"

#include <QFile>
#include <QIODevice>
#include <QMessageBox>
#include <QDebug>
#include <QDateTime>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //初始化服务器信息
    setWindowTitle("Say聊天服务器");
    ui->ser_name->setText("Say聊天");
    ui->ser_name->setReadOnly(true);
    ui->ser_ip->setText("127.0.0.1");
    ui->ser_ip->setReadOnly(true);
    ui->ser_port->setText("8888");
    ui->ser_port->setReadOnly(true);
    ui->p_num->setText("0");
    ui->p_num->setReadOnly(true);
    //获取系统时间
    QDateTime current = QDateTime::currentDateTime();
    QString cur_date = current.toString("yyyy.MM.dd hh:mm:ss ddd");
    ui->textEdit->append(cur_date);
    ui->textEdit->append("服务器启动");
    //连接mysql数据库
    Mysql_data *sql = new Mysql_data;
    QSqlQuery query(sql->db);
    query.exec("select * from data");
    while (true == query.next()) {
        qDebug() << query.value(0).toString()
                 << query.value(1).toString()
                 << query.value(2).toString();
        sql->id.append(query.value(0).toString());
        sql->passwd.append(query.value(1).toString());
        sql->name.append(query.value(2).toString());
    }

    //关闭服务器
    connect(ui->close_ser, &QPushButton::clicked, this, &Widget::close);
    //保存日志
    connect(ui->save, &QPushButton::clicked, this, [=](){
        QFile file("./server.log");
        file.open(QIODevice::ReadWrite|QIODevice::Append);
        QString data_str = ui->textEdit->toPlainText();
        QByteArray line = data_str.toUtf8();
        file.write(line);
        QMessageBox::information(this, "日志保存", "日志保存成功");
    });

    //建立TCP连接 (to many thread)
    m_s = new QTcpServer(this);
    m_s->listen(QHostAddress::Any, 8888);
    connect(m_s, &QTcpServer::newConnection, this, [=](){
        Thread_RDWR *thread = new Thread_RDWR(m_s, ser_t, hash, sql->id, sql->passwd, sql->name);
        thread->start();
        connect(thread, &Thread_RDWR::sendHashData, this, [=](QString str, QTcpSocket *tcp){
            QString cur_date = current.toString("yyyy.MM.dd hh:mm:ss ddd");
            ui->textEdit->append(cur_date);
            ui->textEdit->append(str + "登录");
            people_cnt++;
            ui->p_num->setText(QString::number(people_cnt));
            qDebug() << str;
            hash.insert(str, tcp);
        });
        connect(thread, &Thread_RDWR::sendUsrData, this, [=](QString _id, QString _passwd, QString _name, int operation){
            QByteArray id_ = _id.toUtf8();
            char *uid = id_.data();
            QByteArray passwd_ = _passwd.toUtf8();
            char *upasswd = passwd_.data();
            QByteArray name_ = _name.toUtf8();
            char *uname = name_.data();
            char op[100]={0};
            QSqlQuery q(sql->db);
            if (operation == 1) {
                sprintf(op, "insert into data values('%s', '%s', '%s');", uid, upasswd, uname);
            } else if (operation == 2) {
                sprintf(op, "update data set passwd='%s' where id='%s';", upasswd, uid);
            }
            q.exec(op);
            q.exec("select * from data");
            while (true == q.next()) {
                qDebug() << q.value(0).toString()
                         << q.value(1).toString()
                         << q.value(2).toString();
                sql->id.append(q.value(0).toString());
                sql->passwd.append(q.value(1).toString());
                sql->name.append(q.value(2).toString());
            }
        });

        connect(thread, &Thread_RDWR::updateBroList, this, [=](QTcpSocket *tcp){
            int type = 4;
            tcp->write((char*)&type, 4);
            tcp->write((char*)&people_cnt, 4);
            int len_ = hash.size();
            tcp->write((char*)&len_, 4);
            //更新列表数据
            QHash<QString, QTcpSocket*>::iterator it;
            for (it=hash.begin();it!=hash.end();++it) {
                //tcp->write((char*)&type, 4);
                len_ = it.key().size();
                tcp->write((char*)&len_, 4);
                tcp->write(it.key().toUtf8());
            }
        });

        connect(thread, &Thread_RDWR::sendId_Msg, this, [=](QString from_id, QString to_id, QString msg){
            QString cur_date = current.toString("yyyy.MM.dd hh:mm:ss ddd");
            ui->textEdit->append(cur_date);
            ui->textEdit->append(from_id+" send msg to "+to_id+", msg="+msg);
            //转递到其他用户
            QTcpSocket *tcp = hash[to_id];
            int type = 5;
            tcp->write((char*)&type, 4);
            tcp->write(msg.toUtf8());

        });
        //转发文件
        static int flag = 0;
        connect(thread, &Thread_RDWR::sendFileContent, this, [=](QString from, QString to, int len, QString data){
            if (flag == 0) {
                QString cur_date = current.toString("yyyy.MM.dd hh:mm:ss ddd");
                ui->textEdit->append(cur_date);
                ui->textEdit->append(from+" send file to "+to+", fileName="+data);
            }
            QTcpSocket *tcp = hash[to];
            int type = 6;
            tcp->write((char*)&type, 4);
            tcp->write((char*)&len, 4);
            tcp->write(data.toUtf8());
            flag++;
        });

        connect(thread, &Thread_RDWR::sendAll, this, [=](QString to, QString all){
            QTcpSocket *tcp = hash[to];
            tcp->write(all.toUtf8());
        });
        
        connect(thread, &Thread_RDWR::sendGroupMsg, this, [=](QString from, QString to, QString msg){
            int flag = 0;
            for (int i=0;i<tp.size();i++) {
                if (QString::compare(from, tp[i])==0) {
                    flag = 1;
                    break;
                }
            }
            qDebug() << "size = " << noSay.size();
            for (int i=0;i<noSay.size();i++) {
                qDebug() << from << "-------" << noSay[i];
                if (QString::compare(from, noSay[i])==0) {
                    flag = 1;
                    break;
                }
            }
            qDebug() << "&&&&&" << from;
            if (flag == 0) {
                QString cur_date = current.toString("yyyy.MM.dd hh:mm:ss ddd");
                ui->textEdit->append(cur_date);
                ui->textEdit->append(from+" send msg to "+to+" group, msg="+msg);
                QString target;
                //寻找用户名
                for (int i=0;i<sql->id.size();i++) {
                    if (QString::compare(from, sql->id[i]) == 0) {
                        target = sql->name[i];
                        break;
                    }
                }
                //发送群消息
                QTcpSocket *tcp;
                QHash<QString, QTcpSocket*>::iterator it;
                for (it=hash.begin();it!=hash.end();it++) {
                    if (QString::compare(it.key(), from) == 0) continue;
                    tcp = it.value();
                    int type = 7;
                    tcp->write((char*)&type, 4);
                    int from_len = target.size();
                    tcp->write((char*)&from_len, 4);
                    tcp->write(target.toUtf8());
                    tcp->write(msg.toUtf8());
                }
            }

        });
        //打印禁言，解禁等消息
        connect(thread, &Thread_RDWR::sendTp, this, [=](QString tp_id){
            tp.push_back(tp_id);
            QString cur_date = current.toString("yyyy.MM.dd hh:mm:ss ddd");
            ui->textEdit->append(cur_date);
            ui->textEdit->append("将"+tp_id+"踢出群");
        });
        connect(thread, &Thread_RDWR::sendNoSay, this, [=](QString noSay_){
            noSay.push_back(noSay_);
            QString cur_date = current.toString("yyyy.MM.dd hh:mm:ss ddd");
            ui->textEdit->append(cur_date);
            ui->textEdit->append("将"+noSay_+"禁言");
        });
        connect(thread, &Thread_RDWR::sendOpenSay, this, [=](QString openSay){
            for (int i=0;i<noSay.size();i++) {
                if (QString::compare(noSay[i], openSay)==0) {
                    noSay.remove(i);
                    break;
                }
            }
            QString cur_date = current.toString("yyyy.MM.dd hh:mm:ss ddd");
            ui->textEdit->append(cur_date);
            ui->textEdit->append("将"+openSay+"解禁");
        });

        connect(thread, &Thread_RDWR::over, this, [=](QTcpSocket *tcp){
            QHash<QString, QTcpSocket*>::iterator it;
            for (it=hash.begin();it!=hash.end();) {
                if (it.value() == tcp) {
                    qDebug() << "$$delete: " << it.key();
                    QString cur_date = current.toString("yyyy.MM.dd hh:mm:ss ddd");
                    ui->textEdit->append(cur_date);
                    ui->textEdit->append(it.key() + "退出");
                    it = hash.erase(it);
                    people_cnt--;
                    ui->p_num->setText(QString::number(people_cnt));
                    break;
                }
                ++it;
            }
            tcp->close();
            tcp->deleteLater();
        });
    });



}

Widget::~Widget()
{
    delete ui;
}

